package com.ohuang.simpledb;

import android.app.Application;

import java.util.ArrayList;
import java.util.List;

public class DataProvider<T> {

    private String dataBaseName;
    private DataProviderTransform<T> dataProviderTransform;

    private Application application;

    private SimpleDataBase simpleDataBase;

    public DataProvider(Application application, String dataBaseName, DataProviderTransform<T> dataProviderTransform) {
        this.application = application;
        this.dataBaseName = dataBaseName;
        this.dataProviderTransform = dataProviderTransform;
        init();
    }

    private synchronized void init() {
        if (simpleDataBase == null) {
            simpleDataBase = new SimpleDataBase(application, dataBaseName);
        }
    }

    /**
     * 添加数据 key相同则移除
     *
     * @param t
     */
    public synchronized void add(T t) {
        String key = dataProviderTransform.getKey(t);
        List<SimpleData> simpleDataByKey = simpleDataBase.findSimpleDataByKey(key);
        for (SimpleData simpleData : simpleDataByKey) {
            simpleDataBase.delete(simpleData.id);
        }
        SimpleData simpleData = new SimpleData();
        simpleData.key = key;
        simpleData.data = getData2String(t);
        simpleDataBase.add(simpleData);
    }

    /**
     * 添加数据 key相同不添加  返回true为添加成功
     *
     * @param t
     */
    public synchronized boolean addNotSame(T t) {
        String key = dataProviderTransform.getKey(t);
        List<SimpleData> simpleDataByKey = simpleDataBase.findSimpleDataByKey(key);
        if (simpleDataByKey.size() == 0) {
            SimpleData simpleData = new SimpleData();
            simpleData.key = key;
            simpleData.data = getData2String(t);
            simpleDataBase.add(simpleData);
            return true;
        }
        return false;
    }

    /**
     * 添加数据 key相同更新
     *
     * @param t
     */
    public synchronized void addUpdate(T t) {
        String key = dataProviderTransform.getKey(t);
        List<SimpleData> simpleDataByKey = simpleDataBase.findSimpleDataByKey(key);

        SimpleData simpleData = new SimpleData();
        simpleData.key = key;
        simpleData.data = getData2String(t);

        if (simpleDataByKey.size() == 0) {
            simpleDataBase.add(simpleData);
        } else {
            SimpleData simpleData1 = simpleDataByKey.get(0);
            simpleDataBase.update(simpleData, simpleData1.id);
        }
    }

    /**
     *
     */
    public synchronized boolean update(T t) {
        String key = dataProviderTransform.getKey(t);
        List<SimpleData> simpleDataByKey = simpleDataBase.findSimpleDataByKey(key);
        if (simpleDataByKey.size() == 0) {
            return false;
        }
        SimpleData simpleData = new SimpleData();
        simpleData.key = key;
        simpleData.data = getData2String(t);
        SimpleData simpleData1 = simpleDataByKey.get(0);
        simpleDataBase.update(simpleData, simpleData1.id);
        return true;
    }

    private String getData2String(T t) {
        return dataProviderTransform.data2String(t);
    }

    public synchronized boolean contains(T t) {
        String key = dataProviderTransform.getKey(t);
        List<SimpleData> simpleDataByKey = simpleDataBase.findSimpleDataByKey(key);
        return simpleDataByKey.size() != 0;
    }

    public synchronized void remove(List<T> t) {
        for (T t1 : t) {
            remove(t1);
        }
    }

    public synchronized void remove(T t) {

        String key = dataProviderTransform.getKey(t);
        List<SimpleData> simpleDataByKey = simpleDataBase.findSimpleDataByKey(key);
        if (simpleDataByKey.size() == 0) {
            return;
        }
        SimpleData simpleData = simpleDataByKey.get(0);
        simpleDataBase.delete(simpleData.id);
    }

    private synchronized T getString2data(SimpleData simpleData) {
        return dataProviderTransform.string2data(simpleData.data);
    }

    public synchronized List<T> find(int pageSize, int pageNumber) {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.find(pageSize, pageNumber);
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized List<T> findForDESC(int pageSize, int pageNumber) {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.findForDESC(pageSize, pageNumber);
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized T findByKey(String key) {

        List<SimpleData> simpleDataByKey = simpleDataBase.findSimpleDataByKey(key);
        if (simpleDataByKey.size() == 0) {
            return null;
        }
        return getString2data(simpleDataByKey.get(0));
    }

    public synchronized List<T> findAll() {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.findAll();
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized List<T> findAllForDESC() {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.findAllForDESC();
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized List<T> findSortByKey(int pageSize, int pageNumber) {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.findSortByKey(pageSize, pageNumber);
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized List<T> findSortByKeyForDESC(int pageSize, int pageNumber) {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.findSortByKeyForDESC(pageSize, pageNumber);
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized List<T> findAllSortByKey() {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.findAllSortByKey();
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized List<T> findAllSortByKeyForDESC() {

        List<T> list = new ArrayList<>();
        List<SimpleData> simpleData = simpleDataBase.findAllSortByKeyForDESC();
        for (SimpleData simpleDatum : simpleData) {
            list.add(getString2data(simpleDatum));
        }
        return list;
    }

    public synchronized int getSize() {
        return simpleDataBase.getDataSize();
    }


    public synchronized void deleteAll() {
        simpleDataBase.deleteAll();
    }


}
